class BitAccessor
   
  def initialize(number, number_of_bits_in_window)
    raise(ArgumentError, "First arugment must be a Numeric.  A #{number.class} was passed in: #{number.inspect}.") unless number.is_a? Numeric
    @number = number
    @number_of_bits_in_window = number_of_bits_in_window
    @bit_window = ("1"*number_of_bits_in_window).to_i(2)
  end
  
  def test_bit(bit)
      mask = (1 << bit)
      (self & mask) != 0
  end
  
  def to_i
    @number
  end
  
  def [](index)
    (@number >> index*@number_of_bits_in_window) & @bit_window
  end
  
  def []=(index, value)
    raise(ArgumentError,"The bit window size is #{@number_of_bits_in_window} and the value passed in, #{value}, takes #{value.to_s(2).size} bits.") if value.to_s(2).size > @number_of_bits_in_window
    mask = (@bit_window << index*@number_of_bits_in_window)
    @number = (@number & ~mask) | (value << index*@number_of_bits_in_window)
  end
    
end


# describe BitAccessor do
#   
#   before(:each) do
#     BitAccessor.send(:attr_reader, :bit_window)
#     @ba = BitAccessor.new(160, 3) # 010100000, 111
#   end
#   
#   it "should be able to find the first window's number" do
#     @ba[0].should == 0
#   end
#   
#   it "should be able to find the second window's number" do
#     @ba[1].should == 4
#   end
#   
#   it "should be able to find the third window's number" do
#     @ba[1].should == 4
#   end
#   
#   it "should be able to find the third window's number" do
#     @ba[2].should == 2
#   end
#   
#   it "should be able to set the first window's number" do
#     @ba[0]= 2
#     @ba[0].should == 2
#   end
#   
#   it "should be able to set the first window's number" do
#     @ba[1]= 1
#     @ba[1].should == 1
#   end
#   
#   it "should be able to set the first window's number" do
#     @ba[2]= 4
#     @ba[2].should == 4
#   end
#   
#   it "should raise an error when a value that is passed has too many bits" do
#     lambda {@ba[2].should == 8}.should raise_error
#   end
#   
# end